package com.work.appwork.adminController;


import com.alibaba.fastjson.JSON;
import com.work.appwork.MyInterFace.MyiMua;
import com.work.appwork.request.LoginRequest;
import com.work.appwork.service.AdminService.AdminService;
import com.work.appwork.vo.AdminVo;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RequestMapping(value = {"/admin"})
@RestController
@Api(value = "Admin用户controller",tags = {"Admin用户接口操作"},protocols = "https",hidden = false) //类的请求说明
@Slf4j //用作日志输出
public class AdminContro {

    //锁
//    private final static String lock="lock";
    /**
     *
     * admin 用户信息
     */

    @Autowired
    @Qualifier("AdminVo") //限定词
    private AdminVo adminVo;

    @Resource
    private AdminService adminService;
    @Resource
    RedisTemplate<String,String> redisTemplate;
    @Resource
    RedissonClient redissonClient;

    @GetMapping(value = {"/getAdmin"})
    @ResponseBody
    @ApiOperation(value = "获取admin用户信息",notes = "注意value的填写") //方法的请求说明
    public Map getAdminInfo(@ApiParam(value = "用户名",required = true)
                            @RequestParam(name = "name",defaultValue = "张三") String name){
        Map map=new HashMap();
        map.put("用户名",name);
        AdminVo adminVo1=new AdminVo(1,"w","q");

        //用@Builder 直接赋值操作
        AdminVo adminVo2= AdminVo.builder()
                .adminName("")
                .adminPwd("")
                .build();

        return map;
    }

    @PostMapping(value = {"/saveAdmin"})
    @ApiOperation(value = "保存admin用户信息")
    public String saveAdmin(@ApiParam(value = "用户账号",required = true)
                            @RequestParam(name = "admin",defaultValue = "无")String adminName,
                            @ApiParam(value = "用户密码",required = true)
                            @RequestParam(name = "password",required = true)String adminPass
                            ){
        log.info("进入查询接口");
        return "账号:"+adminName+" "+"密码:"+adminPass;
    }

    @GetMapping
    @ApiOperation(value = "修改Admin信息",notes = "注入一个Admin对象")
    public ResponseEntity update(@RequestBody AdminVo adminVo){
        return ResponseEntity.ok(adminVo);
    }

//    @RequestHeader注解用于映射请求头数据到Controller方法的对应参数


    @ApiOperation(value = "admin查询")
    @PostMapping(value = {"/adminSelect"})
    @ApiImplicitParams(
            {@ApiImplicitParam(name = "adminName",value = "用户名",dataType = "string",paramType = "query") ,
             @ApiImplicitParam(name = "adminPwd",value = "密码",dataType = "string",paramType = "query")})
    public AdminVo  AdminQuery(@RequestBody LoginRequest loginRequest ){
            //先从redis缓存获取
        StringBuffer stringBuffer=new StringBuffer();
        AdminVo adminVo=null;
        String lock="lock";
        RLock lock1= redissonClient.getLock(lock);
        lock1.lock();
         if(StringUtils.isNotBlank(loginRequest.getAdminName())&&StringUtils.isNotBlank(loginRequest.getAdminPwd())){
             log.info("准备登录了{}:{}", loginRequest.getAdminName(), loginRequest.getAdminPwd());
             stringBuffer.append("admin:");
             stringBuffer.append(loginRequest.getAdminName());
             stringBuffer.append(loginRequest.getAdminPwd());
             String key=stringBuffer.toString();
             log.info("redis的key{}",key);
           String data=  redisTemplate.opsForValue().get(key);
           if(StringUtils.isNotBlank(data)){
               adminVo= JSON.parseObject(data,AdminVo.class);
               log.info("从缓存获取用户信息{}",adminVo);
           }else {
               adminVo = adminService.login(loginRequest);
               if(adminVo!=null){
                   log.info("从数据库获取用户信息{}",adminVo);
                   redisTemplate.opsForValue().set(key,JSON.toJSONString(adminVo));
               }
           }
         }
        lock1.unlock();

        return adminVo;
    }

    @ApiOperation(value = "查询用户")//接口文档
    @PostMapping(value = {"/searchAdmin"})
    @ApiImplicitParams({@ApiImplicitParam(name = "adminName",required = true),@ApiImplicitParam(name = "adminPwd",required = true)})

    public AdminVo searchAdmin(@RequestBody LoginRequest loginRequest){
        StringBuffer stringBuffer=new StringBuffer();
        AdminVo adminVo=null;
        String lock="mylock";
        /**
         *  redis 分布式锁 加锁
         * */
        RLock mylock=redissonClient.getLock(lock);
        mylock.lock();
        if(StringUtils.isNotBlank(loginRequest.getAdminName().trim())&&StringUtils.isNotBlank(loginRequest.getAdminPwd().trim())){
            log.info("准备登录用户: {}:{}",loginRequest.getAdminName(),loginRequest.getAdminPwd());
            //准备存储redis的key 数据
            stringBuffer.append("admin:");//
            stringBuffer.append(loginRequest.getAdminName());//追加用户名称
            stringBuffer.append(loginRequest.getAdminPwd());//追加用户密码
            String key=stringBuffer.toString();
            log.info("存储到redis的key{}",key);//储存一个自定的缓存规范
            //从缓存中获取
            String data=redisTemplate.opsForValue().get(key);
            //判断如果data 里面不为空的话
            if(StringUtils.isNotBlank(data)){
                //json数据转换成 bean 对象
                adminVo= JSON.parseObject(data,AdminVo.class);
                //输出log日志
                log.info("从缓存中得到用户信息:{}",adminVo);

            }else {
                //如果缓存中没有 则数据库获取
                adminVo=adminService.login(loginRequest);
                if(adminVo!=null){
                    log.info("从数据库中得到用户信息:{}",adminVo);
                    //存储到 redis缓存中
                    redisTemplate.opsForValue().set(key,JSON.toJSONString(adminVo));
                    System.out.println("redisTemplate.opsForValue().get(key) = " + redisTemplate.opsForValue().get(key));
                }
            }
        }
        /**
         *  redis 分布式锁 释放锁
         * */
        mylock.unlock();
        return adminVo;
    }


    @ApiOperation(value = "添加用户")
    @PostMapping(value = {"/insertAdmin"})
    @ApiImplicitParams(
            {@ApiImplicitParam(name = "adminName",value = "用户名",required = true),
             @ApiImplicitParam(name = "adminPwd",value = "密码",required = true)})
    public String saveAdmin(@RequestBody AdminVo adminVo){
        if(adminVo!=null){
            log.info("数据库存入admin:{}",adminVo);
            Integer result=adminService.saveAdmin(adminVo);
            System.out.println("保存："+result+" 行");
            return "成功保存："+result+" 行";
        }
        return "添加失败！";
    }

    @ApiOperation(value = "admin删除",notes = "注意ID的填写")
    @GetMapping(value = {"/adminDelete/{id}"})
    @ApiParam(name = "id",required = true)
    public String adminDelete(@RequestParam(name = "id") int id){
        StringBuffer stringBuffer=new StringBuffer();
        AdminVo adminVo=null;
        adminVo = adminService.searchAdmin(id);
        String key="";
        if(adminVo!=null){
            stringBuffer.append("admin:");
            stringBuffer.append(adminVo.getAdminName());
            stringBuffer.append(adminVo.getAdminPwd());
             key=stringBuffer.toString();

            log.info("准备删除redis的key{}",key);
            System.out.println("adminVo = " + JSON.toJSONString(adminVo));
            redisTemplate.delete(key);
        }
        if(id!=0){
            log.info("删除id：{}",id);
            Integer result=adminService.adminDelete(id);
            System.out.println("result = " + result);
            redisTemplate.expire(key,1, TimeUnit.SECONDS);
            return "删除账号为 :"+id;
        }
        return "删除失败！";
    }

    @ApiOperation(value = "查询所有")
    @GetMapping("/findAll")
//    @Cacheable(value = "adminList")//缓存一个方法的执行结果
    public List<AdminVo> findAll(){
         List<AdminVo> adminVoList=new ArrayList<>();
         String allKey="users";
        String data= redisTemplate.opsForValue().get(allKey);
        if(StringUtils.isNotBlank(data)){
            adminVoList= JSON.parseArray(data,AdminVo.class);
            log.info("从缓存取");

        }else{
            adminVoList=   adminService.findAll();
            if(!CollectionUtils.isEmpty(adminVoList)){
                //存入缓存
                redisTemplate.opsForValue().set(allKey,JSON.toJSONString(adminVoList));
                log.info("从数据库取");
            }
        }

        return adminVoList;
    }


    @ApiOperation(value = "修改用户信息")
    @PostMapping(value = {"/editAdmin"})
    @ApiImplicitParams({
            @ApiImplicitParam(value = "id",name = "id",required = true),
            @ApiImplicitParam(value = "用户名",name = "adminName",required = true),
            @ApiImplicitParam(value = "密码",name = "adminPwd",required = true)})
    public String editAdmin(@RequestBody AdminVo adminVo){
        StringBuffer stringBuffer=new StringBuffer();
        Integer result=0;
        //查询数据中 未更改的原数据
        AdminVo oldAdmin=adminService.searchAdmin(adminVo.getId());
        //正常时修改，id一定会存在值
        if(StringUtils.isNotBlank(adminVo.getAdminName().trim())||StringUtils.isNotBlank(adminVo.getAdminPwd().trim())){
            //如果传输的数据即使没有做更改，也会有未更改的数据
            //直接修改redis 缓存值 *组装规范
            stringBuffer.append("admin:");
            stringBuffer.append(oldAdmin.getId());
            stringBuffer.append(oldAdmin.getAdminName());
            stringBuffer.append(oldAdmin.getAdminPwd());
            String key=stringBuffer.toString();
            //删除缓存中的数据
            log.info("用户原数据:{}",key);
            redisTemplate.delete(key);
            //修改数据中的数据
            result=adminService.editAdmin(adminVo);
        }
        return "修改受影响行:"+result;
    }

    /***
     * 消息队列
     * */


    /***
     * Mysql 的SQL语句 多表联查 SQL优化 索引  等数据库优化
     * */

    /***
     * elasticsearch 全文搜索引擎
     */



}
